/*************************************
Interfaz para las comunicaciones por el puerto serie
con el PIc de tarjeta de sincronismo
*************************************/

#ifndef _SERIAL_H_
#define _SERIAL_H_

#include <queue>
#include <sys/time.h>

#include "semaphore.h"
#include "serialport.h"

//#define DEBUG_SHOW_SERIALPORT_DATA


typedef struct dato_TX_t{
    unsigned char dato;
    struct timeval t;
} dato_TX_t;


//datos a pasar al interfaz de control del puerto serie
typedef struct serial_params_t {
    //queue_char buffer_ack;//buffer ó cola de datos enviados, esperando a ser comprobados
    std::queue <dato_TX_t> buffer_ack;
    pthread_mutex_t mutex_buffer_tx, mutex_buffer_ack; //semáforos de control de los buffers
    //semáforo para desbloquear el hilo de RETX cuando no hay nada que reenviar
    sem_t sem_retx;
    //dato que hay que reenviar cada TIME_RETX segundos
    unsigned char dato_reenviar;
    int secs_reenviar;

    //handler del puerto serie
    int pport;
    struct termios OldConf; //antigua configuración del puerto
    struct termios NewConf; //nueva configuración del puerto

    //función que será llamada cada vez que se reciba un dato
    bool (*callback_rx)(int , unsigned char , float, struct serial_params_t*, void *);
    void *params; //parámetros a pasar a la función

    bool quit;
    unsigned long datos_recibidos;
    unsigned long datos_perdidos;
    pthread_t hiloRETX, hiloRX;

}serial_params_t;    


/*  \brief Envía un dato al buffer de transmisión. No lo envía directamente, pero se enviará enseguida
 *  \param p  estructura de datos del interfaz de control del puerto, inicializado con empezar_lectura_serialport
 *  \param Data buffer con los datos a enviar
 *  \param SizeData número de datos a enviar
 *  \param reenviar Indica si se quiere reenviar indifinidamente el primer dato pasado
 *  \return El número de datos puestos en el buffer
 */
long Write_Port_buffer(serial_params_t *,unsigned char Data[],int SizeData, bool reenviar = false);
long Write_Port_buffer(serial_params_t *,unsigned char , bool reenviar = false);

/* \brief Abre el puerto serie e Inicializa el interfaz de comunicación por el puerto serie con la placa del PIC
 * \param p Puntero a la estructrua de datos de la interfaz de control
 * \param portname Nombre del puerto serie a abrir
 * \return true si todo fue bien. false si no se puedo abrir el puerto
 */
bool empezar_lectura_serialport(serial_params_t *, const char * );

/* \brief Cierra el puerto serie y el interfaz de comunicación por el puerto serie con la placa del PIC
 * \param p Puntero a la estructrua de datos de la interfaz de control
 */
void terminar_lectura_serialport(serial_params_t *);

/* \brief Indica un dato a reenviar por el puerto serie cada TIME_RETX segundos
 * \param p Puntero a la estructrua de datos de la interfaz de control
 * \param key Dato a reenviar cada TIME_RETX segundos. Si key =0, no reenvia nada
 */
void set_dato_reenviar(serial_params_t * p, unsigned char key, int secs);

bool is_open_port(serial_params_t * p);
bool GetHayDatosRecibidos(serial_params_t *p);

#endif

